package fifteenth.ClassLoader;
//ClassLoader类里面有一个可以把字节数组变成类文件的转换方法

import java.io.*;

public class MyClassLoaderPlus extends ClassLoader{
    public  Class<?> getMyClass(String className) throws IOException {
        byte[] b = this.getFileData(className); //取得指定路径的字节信息
        return super.defineClass(className,b,0,b.length);   //加载类文件数据
    }
    private byte[] getFileData(String className) throws IOException {   //根据文件利用IO流加载类程序
        byte receive[]= null;   //此为接收读取的类文件二进制数据
        File file = new File("D:\\WorkSpaces\\JavaDevelopBase_start_329\\src\\fifteenth\\demo.txt");//定义类文件的加载路径
        FileInputStream fis = new FileInputStream(file);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte [] data=new byte[1024];    //定义每次分块读取数据的长度
        int len = 0;    //保存每次读取进来的字节个数
        while(((len=fis.read())!=-1)){  //循环读取内容并且利用内存输出流保存
            bos.write(data,0,len);  //将数据保存到输出流中
        }
        receive = bos.toByteArray();    //将全部内存数据保存到返回数据
        bos.close();
        fis.close();
        return receive; //返回字节文件数据
    }
}
/**
 * 上面的程序利用文件加载的方式，通过文件流读取指定类的二进制数据，最为关键的是，这个时候文件可以不存在CLASSPATH中，
 * 这样将极大地方便程序的灵活性编写
 * 提问：能否利用自定义了类加载器，加载自己的java.lang.String类
 * 利用ClassLoader可以实现类数据的信息加载操作，那么能否在实际开发中，自己编写一个新的java.lang.String类而后通过ClassLoader类加载呢？
 *
 * 回答：ClassLoader使用双亲加载机制，不能够加载
 * 在ClassLoader类设计时，考虑到程序的安全性设计，在整个开发过程之中，ClassLoader类对于类的加载使用了双亲加载机制，
 * 也就是说系统类库依然使用系统的类加载器，而只有非系统类库才可以使用自己的Classloader,这样就保证了程序的安全性。
 * java.lang.String是系统类的名字，这个类一定只能够被系统类加载器控制，用户无法定义与之一样的类来实现加载。
 */